package mini.expr;

import java.util.LinkedList;
import java.util.List;

import mini.Env;
import mini.Proc;
import mini.expr.lists.ElementList;
import mini.oo.MiniClassInstantiation;


public class Element extends Expr {
    private Integer intValue;
    private ElementList listValue;
    private Proc procValue;
    private MiniClassInstantiation classValue;
    
    public Element() {
    }
    
    public Element(Integer intValue) {
        setIntValue(intValue);
    }
    
    public Element(ElementList listValue) {
        setListValue(listValue);
    }

    public Element(Proc procValue) {
        setProcValue(procValue);
    }

    public Element(MiniClassInstantiation classValue) {
        setClassValue(classValue);
    }

    public MiniClassInstantiation getClassValue() {
        return classValue;
    }

    public void setClassValue(MiniClassInstantiation classValue) {
        this.classValue = classValue;
    }

    public Integer getIntValue() {
        return intValue;
    }

    public void setIntValue(Integer intValue) {
        this.intValue = intValue;
    }

    public Proc getProcValue() {
        return procValue;
    }

    public void setProcValue(Proc procValue) {
        this.procValue = procValue;
    }

    public ElementList getListValue() {
        return listValue;
    }

    public void setListValue(ElementList listValue) {
        this.listValue = listValue;
    }
    
    public boolean isList() {
        return listValue != null;
    }
    
    public boolean isInt() {
        return intValue != null;
    }
    
    public boolean isProc() {
        return procValue != null;
    }
    
    public boolean isClass() {
        return classValue != null;
    }
    
    @Override
    public String toString() {
    	if( isInt() ) {
    		return toStringInt();
    	} else if( isList() ) {
    		return toStringList();
    	} else if( isProc() ) {
    		return toStringProc();
    	} else if( isClass() ) {
    		return toStringClass();
    	}
    	
    	return "[Element ?]";
    }
    
    @Override
    public Element eval(List<Env> listOfEnvs, LinkedList var) {
        
        if (isList()) {
            listValue.eval(listOfEnvs, var);
        }
        
        return this;
    }
    
    public String toStringInt() {
        return intValue.toString();
    }
    
    public String toStringProc() {
        return procValue.toString();
    }
    
    public String toStringList() {
        return listValue.toString();
    }
    
    public String toStringClass() {
        return classValue.toString();
    }
    
    public Element clone() {
        Element newElement = new Element();
        
        newElement.intValue = intValue;
        
        newElement.procValue = procValue;

        newElement.classValue = classValue;
        
        if (listValue != null) {
            newElement.listValue = listValue.clone();
        }
        
        return newElement;
    }
}
